import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import { miniprogramCIService } from './services/miniprogram-ci-service.js';

export function activate(context: vscode.ExtensionContext) {
  // 注册命令以打开 Webview 弹窗
  let disposable = vscode.commands.registerCommand('miniprogram-ci-helper.open', () => {
    // 获取当前工作目录
    const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
    const workspacePath = workspaceFolder?.uri.fsPath || '';
    
    // 创建并显示新的 Webview 弹窗
    const panel = vscode.window.createWebviewPanel(
      'miniprogramCiHelper',
      '微信小程序CI助手',
      vscode.ViewColumn.Active, // 使用Active使其成为浮动窗口
      {
        // 允许脚本在 Webview 中运行
        enableScripts: true,
        // 限制 Webview 只能加载我们的扩展中的资源
        localResourceRoots: [
          vscode.Uri.file(path.join(context.extensionPath, 'dist/webview'))
        ],
        // 弹窗相关配置
        retainContextWhenHidden: true,
        enableFindWidget: false
      }
    );

    // 设置弹窗的尺寸和位置
    panel.reveal(undefined, true);

    // 设置 Webview 内容
    panel.webview.html = getWebviewContent(panel.webview, context.extensionPath, workspacePath);

    // 处理来自 Webview 的消息
    panel.webview.onDidReceiveMessage(
      async (message) => {
        switch (message.command) {
          case 'selectDevProjectPath':
            const devProjectPath = await vscode.window.showOpenDialog({
              canSelectFolders: true,
              canSelectFiles: false,
              canSelectMany: false,
              title: 'Select Development Miniprogram Project Folder'
            });
            
            if (devProjectPath && devProjectPath[0]) {
              panel.webview.postMessage({
                command: 'devProjectPathSelected',
                path: devProjectPath[0].fsPath
              });
            }
            return;

          case 'selectProdProjectPath':
            const prodProjectPath = await vscode.window.showOpenDialog({
              canSelectFolders: true,
              canSelectFiles: false,
              canSelectMany: false,
              title: 'Select Production Miniprogram Project Folder'
            });
            
            if (prodProjectPath && prodProjectPath[0]) {
              panel.webview.postMessage({
                command: 'prodProjectPathSelected',
                path: prodProjectPath[0].fsPath
              });
            }
            return;
            
          case 'selectPrivateKeyPath':
            const privateKeyPath = await vscode.window.showOpenDialog({
              canSelectFolders: false,
              canSelectFiles: true,
              canSelectMany: false,
              filters: { 'Private Key': ['key'] },
              title: 'Select Private Key File'
            });
            
            if (privateKeyPath && privateKeyPath[0]) {
              panel.webview.postMessage({
                command: 'privateKeyPathSelected',
                path: privateKeyPath[0].fsPath
              });
            }
            return;
            
          case 'upload':
            await handleUpload(panel, message.data);
            return;
            
          case 'preview':
            await handlePreview(panel, message.data);
            return;
            
          case 'npmBuild':
            await handleNpmBuild(panel, message.data);
            return;
            
          case 'showNotification':
            vscode.window.showInformationMessage(message.text);
            return;
            
          case 'showError':
            vscode.window.showErrorMessage(message.text);
            return;
        }
      },
      undefined,
      context.subscriptions
    );
  });

  context.subscriptions.push(disposable);

  // 注册快速预览命令
  let quickPreviewDisposable = vscode.commands.registerCommand('miniprogram-ci-helper.quickPreview', async () => {
    return await handleQuickPreview(context);
  });

  // 注册测试命令
  let testCommandDisposable = vscode.commands.registerCommand('miniprogram-ci-helper.testQuickPreview', async () => {
    try {
      const result = await vscode.commands.executeCommand('miniprogram-ci-helper.quickPreview');
      console.log('测试命令返回值:', result);
      vscode.window.showInformationMessage(`测试完成，返回值: ${JSON.stringify(result)}`);
      return result;
    } catch (error) {
      console.error('测试命令执行失败:', error);
      vscode.window.showErrorMessage(`测试失败: ${error}`);
      return { success: false, error: error };
    }
  });

  context.subscriptions.push(quickPreviewDisposable, testCommandDisposable);
}

// 生成 Webview 内容
function getWebviewContent(webview: vscode.Webview, extensionPath: string, workspacePath: string = '') {
  // 获取构建后的 React 应用的 URI
  const scriptUri = webview.asWebviewUri(vscode.Uri.file(
    path.join(extensionPath, 'dist/webview', 'index.js')
  ));
  
  const styleUri = webview.asWebviewUri(vscode.Uri.file(
    path.join(extensionPath, 'dist/webview', 'index.css')
  ));

  // 计算默认路径
  const devDefaultPath = workspacePath ? path.join(workspacePath, 'mini', 'dist', 'weapp', 'development') : '';
  const prodDefaultPath = workspacePath ? path.join(workspacePath, 'mini', 'dist', 'weapp', 'production') : '';
  const privateKeyDefaultPath = workspacePath ? path.join(workspacePath, 'mini', 'certs', 'private.upload.key') : '';
  const defaultAppid = '';

  // 使用随机的非cecksum值来绕过VS Code的缓存
  const nonce = getNonce();

  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; script-src 'nonce-${nonce}'; img-src ${webview.cspSource} data:;">
  <link rel="stylesheet" href="${styleUri}">
  <title>Miniprogram CI Helper</title>
</head>
<body>
  <div id="root"></div>
  <script nonce="${nonce}" src="${scriptUri}"></script>
  <script nonce="${nonce}">
    // 注入默认路径到全局变量
    window.defaultPaths = {
      dev: ${JSON.stringify(devDefaultPath)},
      prod: ${JSON.stringify(prodDefaultPath)},
      privateKey: ${JSON.stringify(privateKeyDefaultPath)},
      appid: ${JSON.stringify(defaultAppid)}
    };
  </script>
</body>
</html>`;
}

// 生成随机nonce值
function getNonce() {
  let text = '';
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  for (let i = 0; i < 32; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

// 处理上传操作
async function handleUpload(panel: vscode.WebviewPanel, data: any) {
  const result = await miniprogramCIService.upload(data, panel);
  panel.webview.postMessage({
    command: 'uploadResult',
    data: result
  });
}

// 处理预览操作
async function handlePreview(panel: vscode.WebviewPanel, data: any) {
  const result = await miniprogramCIService.preview(data, panel);
  panel.webview.postMessage({
    command: 'previewResult',
    data: result
  });
}

// 处理npm构建操作
async function handleNpmBuild(panel: vscode.WebviewPanel, data: any) {
  const result = await miniprogramCIService.npmBuild(data, panel);
  panel.webview.postMessage({
    command: 'buildResult',
    data: result
  });
}
// 处理快速预览命令
async function handleQuickPreview(context: vscode.ExtensionContext): Promise<any> {
  try {
    // 获取当前工作目录
    const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
    if (!workspaceFolder) {
      vscode.window.showErrorMessage('请先打开一个工作目录');
      return { success: false, error: '请先打开一个工作目录' };
    }

    const workspacePath = workspaceFolder.uri.fsPath;
    // 小程序开发版项目路径
    const miniDevProjectPath = path.join(workspacePath, 'mini', 'dist', 'weapp', 'development');
    // 检查配置文件是否存在
    const configPath = path.join(miniDevProjectPath, 'project.config.json');
    let appid = '';
    let projectPath = '';
    let privateKeyPath = '';

    if (fs.existsSync(configPath)) {
      try {
        const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
        appid = config.appid || '';
        projectPath = path.join(miniDevProjectPath, config.miniprogramRoot || '');
      } catch (error) {
        vscode.window.showErrorMessage('读取 project.config.json 失败');
        return { success: false, error: '读取 project.config.json 失败' };
      }
    }

    // 如果没有appid，弹出输入框
    if (!appid) {
      const inputAppid = await vscode.window.showInputBox({
        prompt: '请输入小程序 APP ID',
        placeHolder: '例如: wx1234567890abcdef',
        validateInput: (value) => {
          if (!value || !value.startsWith('wx')) {
            return '请输入有效的小程序 APP ID';
          }
          return null;
        }
      });

      if (!inputAppid) {
          return { success: false, error: '用户取消了输入 APP ID' };
        }

      appid = inputAppid;

      // 保存到配置文件
      try {
        const config = fs.existsSync(configPath) 
          ? JSON.parse(fs.readFileSync(configPath, 'utf-8')) 
          : {};
        
        config.appid = appid;
        fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
      } catch (error) {
        vscode.window.showWarningMessage('保存 APP ID 到配置文件失败');
      }
    }

    // 如果没有项目路径，使用默认路径
    if (!projectPath || !fs.existsSync(projectPath)) {
      projectPath = miniDevProjectPath;
    }

    // 检查项目路径是否存在
    if (!fs.existsSync(projectPath)) {
      vscode.window.showErrorMessage(`项目路径不存在: ${projectPath}`);
      return { success: false, error: `项目路径不存在: ${projectPath}` };
    }

    // 查找私钥文件
    const possibleKeyPaths = [
      path.join(workspacePath, 'mini', 'certs', 'private.upload.key'),
    ];

    for (const keyPath of possibleKeyPaths) {
      if (fs.existsSync(keyPath)) {
        privateKeyPath = keyPath;
        break;
      }
    }

    if (!privateKeyPath) {
      const keyUri = await vscode.window.showOpenDialog({
        canSelectFiles: true,
        canSelectFolders: false,
        canSelectMany: false,
        filters: { 'Private Key': ['key'] },
        title: '选择小程序上传私钥文件'
      });

      if (!keyUri || !keyUri[0]) {
        return { success: false, error: '用户取消了选择私钥文件' };
      }

      privateKeyPath = keyUri[0].fsPath;
    }

    // 执行预览
    const result = await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: '正在生成小程序预览...',
      cancellable: false
    }, async (progress) => {
      try {
        progress.report({ increment: 0, message: '正在准备项目...' });

        const previewOptions = {
          projectPath,
          privateKeyPath,
          appid,
          type: 'miniProgram',
          version: '',
          desc: '快速预览'
        };

        progress.report({ increment: 20, message: '正在创建项目实例...' });

        const result = await miniprogramCIService.preview(previewOptions);
        
        if (result.success) {
          progress.report({ increment: 100, message: '预览生成成功！' });
          
          // 显示二维码在消息提示中
          if (result.result.qrcode) {
            vscode.window.showInformationMessage('小程序预览已生成完成！')
          } else {
            vscode.window.showInformationMessage('预览生成成功！');
          }
          
          return {
            success: true,
            qrcode: result.result.qrcode,
            appid: appid,
            projectPath: projectPath
          };
        } else {
          throw new Error(result.error || '预览失败');
        }
      } catch (error: any) {
        vscode.window.showErrorMessage(`预览失败: ${error.message}`);
        throw error;
      }
    });

    return result;
  } catch (error: any) {
    vscode.window.showErrorMessage(`操作失败: ${error.message}`);
    return { success: false, error: error.message };
  }
}



export function deactivate() {}
